package com.jxmcloud.business.cut.handler;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jxmcloud.business.cut.mapper.json.IConfigItemMapper;
import com.jxmcloud.business.cut.model.activity.Bag;
import com.jxmcloud.business.cut.model.json.ConfigItem;
import com.jxmcloud.business.cut.util.SpringUtils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 处理背包JSON字符串与Set<Bag>对象之间的转换
 */
public class BagSetTypeHandler extends BaseTypeHandler<Set<Bag>> {

    private static final Logger logger = LoggerFactory.getLogger(BagSetTypeHandler.class);
    private static final ObjectMapper objectMapper = new ObjectMapper();


    // 每次使用时从SpringUtils获取，而不是注入
    private IConfigItemMapper getConfigItemMapper() {
        return SpringUtils.getBean(IConfigItemMapper.class);
    }


    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Set<Bag> parameter, JdbcType jdbcType) throws SQLException {
        try {
            ps.setString(i, objectMapper.writeValueAsString(parameter));
        } catch (JsonProcessingException e) {
            logger.error("将Set<Bag>转换为JSON字符串失败", e);
            throw new SQLException("将Set<Bag>转换为JSON字符串失败", e);
        }
    }

    @Override
    public Set<Bag> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        Set<Bag> bagSet = parseJson(rs.getString(columnName));
        // 填充道具名称
        fillItemNames(bagSet);
        return bagSet;
    }

    @Override
    public Set<Bag> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        Set<Bag> bagSet = parseJson(rs.getString(columnIndex));
        // 填充道具名称
        fillItemNames(bagSet);
        return bagSet;
    }

    @Override
    public Set<Bag> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        Set<Bag> bagSet = parseJson(cs.getString(columnIndex));
        // 填充道具名称
        fillItemNames(bagSet);
        return bagSet;
    }

    private Set<Bag> parseJson(String json) {
        if (json == null || json.isEmpty()) {
            return new HashSet<>();
        }

        try {
            return objectMapper.readValue(json, new TypeReference<Set<Bag>>() {
            });
        } catch (IOException e) {
            logger.error("解析JSON字符串为Set<Bag>失败: {}", json, e);
            return new HashSet<>();
        }
    }

    private void fillItemNames(Set<Bag> bagSet) {
        if (bagSet == null || bagSet.isEmpty()) {
            return;
        }

        try {
            // 获取mapper实例
            IConfigItemMapper configItemMapper = getConfigItemMapper();

            // 收集所有道具ID
            Set<Integer> itemIds = bagSet.stream()
                    .map(Bag::getK)
                    .collect(Collectors.toSet());

            // 批量查询道具信息
            List<ConfigItem> items = configItemMapper.selectBatchIds(itemIds);
            Map<Integer, String> itemNameMap = items.stream()
                    .collect(Collectors.toMap(ConfigItem::getId, ConfigItem::getName));

            // 设置道具名称
             bagSet.forEach(bag -> bag.setName(itemNameMap.get(bag.getK())));
        } catch (Exception e) {
            logger.error("填充道具名称失败", e);
        }
    }
}